package test.mdd

import org.goodsl.mdd.annotation.ValueType
import org.junit.Test
import org.goodsl.mdd.Box
import org.goodsl.mdd.Seg
import org.goodsl.mdd.BoxBuilder

import org.junit.Before
import org.goodsl.mdd.ValidResult
import org.goodsl.mdd.annotation.Setting
import org.goodsl.mdd.annotation.Nullable
import org.goodsl.mdd.validator.Default

/**
 * Created with IntelliJ IDEA.
 * User: Simon Xiao
 * Date: 12-11-12
 * Time: 下午3:39
 * To change this template use File | Settings | File Templates.
 */
class TestValidator {

    BoxValid box
    ValidResult result

    @Before
    void setUp() {
        box = (BoxValid) BoxBuilder.makeBox(BoxValid)
    }


    @Test
    void testValidParse() {
        Object[] dd = box.age.validator()
        assert dd.size() > 0
        assert box.age.segInfo.validators.size() > 0
    }

    @Test
    void testMin() {
        box.age 4
        result = box.age.verify()
        assert !result.isValid
        assert result.failCount == 1

        int msgCount = 0;
        result.messages().each {
            msgCount++
        }
        assert msgCount == 1

        box.age 6
        result = box.age.verify()
        assert result.isValid

    }

    @Test
    void testMax() {
        box.age(99)
        result = box.age.verify()
        assert !result.isValid
        box.age  6
        result = box.age.verify()
        assert result.isValid

    }

    @Test
    void testSize() {
        box.name "yu"
        result = box.name.verify()
        assert !result.isValid
        box.name  "yuyuyu"
        result = box.name.verify()
        assert result.isValid
    }

    @Test
    void testPattern() {
        box.name("yuwtewt")
        result = box.name.verify()
        assert result.isValid

        box.name  "yuwte12"
        result = box.name.verify()
        assert !result.isValid
    }

    @Test
    void testPast() {
        box.birthDay new Date(3012 - 1900, 1, 1,)
        result = box.birthDay.verify()
        assert !result.isValid
        box.birthDay new Date(2012 - 1900, 1, 1,)
        result = box.birthDay.verify()
        assert result.isValid
    }

    @Test
    void testDigits() {
        box.age 7
        result = box.age.verify()
        assert result.isValid

        box.id "gorgergeh"
        result = box.id.verify()
        assert !result.isValid

        box.id "50380530535"
        result = box.id.verify()
        assert result.isValid
    }

    @Test
    void testUrl() {
        box.netAddress  "sina.com.cn/i/ec/2012-11-14/04417795834.shtml"
        box.ftpAddress  "http://tech.sina.com.cn/i/ec/2012-11-14/04417795834.shtml"
        result = box.netAddress.verify()
        assert !result.isValid
        result = box.ftpAddress.verify()
        assert !result.isValid

        box.netAddress  "http://tech.sina.com.cn/i/ec/2012-11-14/04417795834.shtml"
        box.ftpAddress  "ftp://tech.sina.com.cn/i/ec/2012-11-14/04417795834.shtml"
        result = box.netAddress.verify()
        assert result.isValid
        result = box.ftpAddress.verify()
        assert result.isValid
    }

    @Test
    void testEmail() {
        box.masterEmail  "simonxiao"
        result = box.masterEmail.verify()
        assert !result.isValid

        box.masterEmail  "simonxiao@gmail.com"
        result = box.masterEmail.verify()
        assert result.isValid
    }

    @Test
    void testNotBlank() {
        box.passWord  ""
        result = box.passWord.verify()
        assert !result.isValid
        assert result.failCount == 1

        result.messages().next() ==  "不能为空"



        box.passWord  "mypassword"
        result = box.passWord.verify()
        assert result.isValid

    }

    @Test
    void testClosureValidator() {
        box.telNumber  "13002118895"
        result = box.telNumber.verify()
        assert !result.isValid
        assert result.messages().next() == "必须135开头"

        box.telNumber  "13502118895"
        result = box.telNumber.verify()
        assert result.isValid
    }

    @Test
    void testAllowNull() {
        box.netAddress  ""

        result = box.netAddress.verify()
        assert result.isValid


    }

    @Test
    void testBoxNullable(){

        box.age  27
        box.name  "simon"
        box.id  "2342525"
        box.telNumber  "135223255"
        box.passWord  "mypassword"
        //以上是避免其他字段出现校验错误



        result = box.verify()
        assert !result.isValid

        dumpResult(result)

        //两个 邮箱 masterEmail 和 secondEmail 都没有填写
        //但是只会报一个错误，因为secondEmail 设置了 Nullable
        assert result.failCount ==1

        box.masterEmail  "simonxiao@gmail.com"
        result = box.verify()
        assert result.isValid

        //虽然 address 设置了Nullable ,不填写可以不校验
        //但是填写了就要满足相应的校验规则
        box.address  "南枫大厦"
        result = box.verify()
        assert !result.isValid

   }

    //测试多字段组合校验
    @Test
    void testBoxCombValid(){


        box.name  "simon"
        box.id  "2342525"
        box.telNumber  "135223255"
        box.passWord  "mypassword"
        box.masterEmail  "simonxiao@gmail.com"
        //以上是避免其他字段出现校验错误


        //校验规则：如果年龄小于18岁，则‘家庭住址’必须填写
        box.age  15
        result = box.verify()
        assert !result.isValid
        box.address  "水荫路52号大院南枫大厦9层"
        result = box.verify()
        dumpResult(result)
        assert result.isValid
    }

    private void dumpResult(ValidResult result){
        if(!result.isValid ){
             result.messages().each {
                 println it
             }
         }
    }

}

class BoxValid extends Box {
    @Setting(alias = "年龄")
    ManAge age
    @Setting(alias ="姓名")
    UserName name
    @Setting(alias ="密码")
    PassWord passWord

    @Setting(alias ="出生日期")
    BirthDay birthDay
    @Setting(alias ="身份证号")
    HumanID id
    @Setting(alias ="家庭住址",nullable = true)
    Address address


    NetAddress netAddress

    @Setting(nullable = true)
    FtpAddress ftpAddress
    @Setting(alias ="邮箱")
    EmailAddress masterEmail
    @Setting(alias ="备用邮箱",nullable = true)

    EmailAddress secondEmail

    Tel telNumber

    //组合校验

    def validator = {
        [
                comp("如果年龄小于18岁，则‘家庭住址’必须填写") {
                    if(this.age > 18)
                        return true
                    else
                        address.value!=null && address.value.toString().length()>0
                }
        ]

    }

}

@ValueType(int)
class ManAge extends Seg {


    def validator = {
        use(Default) {
            [
                    Min(5),
                    Max(98),
                    Digits()
            ]
        }
    }
}
@ValueType(String)
class UserName extends Seg {
    //
    def validator = {
        use(Default) {
            [

                    Size(5, 8),
                    Pattern("[a-zA-Z]*", "用户名只能为字母")

            ]
        }
    }
}
@ValueType(Date)
class BirthDay extends Seg {
    def validator = {
        use(Default) {
            [
                    Past()

            ]
        }
    }
}

@ValueType(String)
class HumanID extends Seg {
    def validator = {
        use(Default) {
            [
                    Digits()
            ]
        }
    }
}

@ValueType(String)
class NetAddress extends Seg {
    def validator = {
        use(Default) {
            [
                    Url(),
                    AllowNull()
            ]
        }
    }
}

@ValueType(String)
class FtpAddress extends Seg {
    def validator = {
        use(Default) {
            [
                    Url("ftp", "必须是ftp地址")
            ]
        }
    }
}

@ValueType(String)
class EmailAddress extends Seg {
    def validator = {
        use(Default) {
            [
                    Email()
            ]
        }
    }
}

@ValueType(String)
class Tel extends Seg {
    def validator = {
        use(Default) {
            [
                    Digits(),
                    CCC("必须135开头") {
                        this.value.toString().startsWith("135")
                    }
            ]
        }
    }
}

@ValueType(String)
class PassWord extends Seg{
    def validator = {
        use(Default) {
            [
                    NotBlank()
            ]
        }
    }
}

@ValueType(String)
class Address extends Seg{
    def validator = {
        use(Default) {
            [
                    Size(10,100)
            ]
        }
    }
}

